package cn.t.facade.user;


import cn.t.converter.user.UserQueryDTOConverter;
import cn.t.core.facade.FacadeImpl;
import cn.t.core.mode.PageInfoDTO;
import cn.t.core.mode.PageQueryDTO;
import cn.t.core.mode.SortedParamDTO;
import cn.t.dto.user.UserQueryDTO;
import cn.t.enums.user.RoleTypeEnum;
import cn.t.enums.user.UpdateEventTypeEnum;
import cn.t.model.user.UserInfoDO;
import cn.t.model.user.UserQueryDO;
import cn.t.service.user.UserInfoService;
import cn.t.service.user.UserQueryService;
import cn.t.user.converter.UserQueryVOConverter;
import cn.t.user.event.UserQueryUpdateEvent;
import cn.t.utils.JsonUtil;
import cn.t.vo.user.FirmVO;
import cn.t.vo.user.ParticipantVO;
import cn.t.vo.user.RoleVO;
import cn.t.vo.user.UserSessionVO;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 场景信息表服务编排
 *
 * @author l
 */
@Slf4j
@Service
@AllArgsConstructor
public class UserQueryFacade extends FacadeImpl<UserQueryDTO, UserQueryDO, UserQueryDTOConverter, UserQueryService> {

    public List<UserQueryDTO> findByFirmId(Long firmId) {
        List<UserQueryDO> tmp = service.findByFirmId(firmId);
        if (CollectionUtils.isEmpty(tmp)) {
            return null;
        }
        return tmp.stream().map(converter::model2Dto).collect(Collectors.toList());
    }

    public UserSessionVO combineSession(Integer scenarioCode, UserSessionVO session) {

        session.setScenarioId(scenarioCode);

        if (session.getUserId() == null || session.getUserId() == 0) {
            return session;
        }

        UserQueryDO userQuery = service.findById(session.getUserId());
        if (userQuery == null) {
            return session;
        }

        session.setPassportVO(userQueryVOConverter.convertPassport(userQuery.getPassportJson()));
        session.setIndividualVO(userQueryVOConverter.individualJson(userQuery.getIndividualJson()));
        session.setFirms(userQueryVOConverter.convertFirms(userQuery.getParticipantJson()));

        return session;
    }

    public void updateByCostCenterId(Long firmId) {
        List<UserQueryDO> list = service.findByCostCenterId(firmId);
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        for (UserQueryDO userQueryDO : list) {
            applicationEventPublisher.publishEvent(new UserQueryUpdateEvent(userQueryDO.getId(), userSessionFacade.operatorInfo(), userQueryDO.getId(), UpdateEventTypeEnum.NONE, UpdateEventTypeEnum.ADD, UpdateEventTypeEnum.NONE));
        }
    }

    public void updateByFirmId(Long firmId) {
        List<UserQueryDO> list = service.findByFirmId(firmId);
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        for (UserQueryDO userQueryDO : list) {
            applicationEventPublisher.publishEvent(new UserQueryUpdateEvent(userQueryDO.getId(), userSessionFacade.operatorInfo(), userQueryDO.getId(), UpdateEventTypeEnum.NONE, UpdateEventTypeEnum.ADD, UpdateEventTypeEnum.NONE));
        }
    }

    public PageInfoDTO<UserQueryDTO> findEntUserPage(PageQueryDTO<UserQueryDTO> queryDTO) {
        SortedParamDTO sortedParamDTO = queryDTO.getSortParam();
        List<UserQueryDTO> list = this.queryList(queryDTO.getParam(), queryDTO.getStart(), queryDTO.getPageSize(), sortedParamDTO.getField(), sortedParamDTO.getDirection());
        if (CollectionUtils.isEmpty(list)) {
            return new PageInfoDTO<>(queryDTO.getPageNo(), queryDTO.getPageSize(), 0L, Collections.emptyList());
        }
        // 填充领料权限组
        list.forEach(f -> {
            List<FirmVO> firms = JsonUtil.parseList(f.getParticipantJson(), FirmVO.class);
            if (CollectionUtils.isEmpty(firms)) {
                return;
            }
            firms.stream().filter(ff -> ff.getFirmCode().equals(queryDTO.getParam().getFirmCode())).findFirst().ifPresent(fff -> {
                if (CollectionUtils.isEmpty(fff.getParticipants())) {
                    return;
                }
                List<RoleVO> roles = new ArrayList<>();
                fff.getParticipants().forEach(p -> {
                    if (!CollectionUtils.isEmpty(p.getRoles())) {
                        roles.addAll(p.getRoles());
                    }
                });
                // 取第一个领料角色
                roles.stream().filter(r -> RoleTypeEnum.MATERIAL_ISSUE.getCode().equals(r.getRoleType())).findFirst().ifPresent(r -> {
                    f.setRoleCode(r.getRoleCode());
                    f.setRoleId(r.getRoleId());
                    f.setRoleName(r.getRoleName());
                });
            });
        });

        long total = queryDTO.getTotal();
        if (queryDTO.isNotNeedPageQuery()) {
            total = this.count(queryDTO.getParam());
        }

        return new PageInfoDTO<>(queryDTO.getPageNo(), queryDTO.getPageSize(), total, list);
    }

    public void refreshAll() {
        List<UserInfoDO> userInfoList = userInfoService.findByModel(null, 0, 9999, null, null);
        for(UserInfoDO userInfoDO : userInfoList){
            applicationEventPublisher.publishEvent(new UserQueryUpdateEvent(userInfoDO.getId(), userSessionFacade.operatorInfo(), userInfoDO.getId(), UpdateEventTypeEnum.UPDATE, UpdateEventTypeEnum.UPDATE, UpdateEventTypeEnum.UPDATE));
        }

    }

    public static void main(String[] args) {

        String json = "[{\"firm\": {\"firmCode\": \"06011111111\", \"firmName\": \"侯凯测试企业\", \"customerId\": 1}, \"scenarioId\": 1, \"costCenterId\": 1, \"participantId\": 11, \"costCenterCode\": \"11111\", \"costCenterName\": \"costName111\"}]";
        ObjectMapper mapper = new ObjectMapper();
        try {
            JavaType type = mapper.getTypeFactory().constructCollectionType(List.class, ParticipantVO.class);

            Object result = mapper.readValue(json, type);

            System.out.println(result.getClass());
            System.out.println(result);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

    }


    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @Autowired
    private UserSessionFacade userSessionFacade;

    @Autowired
    private UserQueryVOConverter userQueryVOConverter;

    private UserInfoService userInfoService;


}

